package router

import (
	"reflect"
	"runtime"
	"strings"

	"gitee.com/war2001/NiuMaEasyGo/model"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// Router 路由管理器
type Router struct {
	Engine           *gin.Engine
	RouteMetadataMap map[string]RouteMetadata // 路由元数据映射表，key为路由路径
	DB               *gorm.DB                 // 数据库连接，用于生成菜单
}

// Config 路由配置
type Config struct {
	Mode       string
	Port       int
	APIPrefix  string
	StaticPath string
}

// New 创建路由实例
func New(config *Config) *Router {
	// 设置gin模式
	if config.Mode == "production" {
		gin.SetMode(gin.ReleaseMode)
	} else if config.Mode == "test" {
		gin.SetMode(gin.TestMode)
	} else {
		gin.SetMode(gin.DebugMode)
	}

	return &Router{
		Engine:           gin.Default(),
		RouteMetadataMap: make(map[string]RouteMetadata),
	}
}

// SetDB 设置数据库连接
func (r *Router) SetDB(db *gorm.DB) {
	r.DB = db
}

// Group 创建路由组
func (r *Router) Group(relativePath string, handlers ...gin.HandlerFunc) *RouterGroup {
	return &RouterGroup{
		RouterGroup: r.Engine.Group(relativePath, handlers...),
		router:      r,
	}
}

// RouterGroup 路由组
type RouterGroup struct {
	*gin.RouterGroup
	router *Router
}

// RegisterController 注册控制器
func (g *RouterGroup) RegisterController(controller interface{}) {
	controllerType := reflect.TypeOf(controller)
	controllerValue := reflect.ValueOf(controller)

	// 遍历控制器的方法
	for i := 0; i < controllerType.NumMethod(); i++ {
		method := controllerType.Method(i)

		// 检查方法是否有元数据函数
		metadataFuncName := method.Name + "Metadata"
		metadataMethod, exists := controllerType.MethodByName(metadataFuncName)

		if exists {
			// 调用元数据函数获取路由元数据
			metadataValues := metadataMethod.Func.Call([]reflect.Value{controllerValue})
			if len(metadataValues) > 0 {
				metadata, ok := metadataValues[0].Interface().(RouteMetadata)
				if ok {
					// 获取处理函数
					handlerFunc := controllerValue.Method(i).Interface().(func(*gin.Context))

					// 注册路由
					switch metadata.Method {
					case "GET":
						g.GET(metadata.APIPath, handlerFunc)
					case "POST":
						g.POST(metadata.APIPath, handlerFunc)
					case "PUT":
						g.PUT(metadata.APIPath, handlerFunc)
					case "DELETE":
						g.DELETE(metadata.APIPath, handlerFunc)
					case "PATCH":
						g.PATCH(metadata.APIPath, handlerFunc)
					case "OPTIONS":
						g.OPTIONS(metadata.APIPath, handlerFunc)
					case "HEAD":
						g.HEAD(metadata.APIPath, handlerFunc)
					default:
						g.GET(metadata.APIPath, handlerFunc)
					}

					// 存储路由元数据
					key := g.BasePath() + metadata.APIPath
					g.router.RouteMetadataMap[key] = metadata
				}
			}
		}
	}
}

// GenerateMenus 根据路由元数据生成菜单
func (r *Router) GenerateMenus() []*model.SysMenu {
	menuMap := make(map[string]*model.SysMenu)
	menuList := make([]*model.SysMenu, 0)

	// 第一步：创建所有目录和菜单
	for _, metadata := range r.RouteMetadataMap {
		// 跳过按钮类型
		if metadata.MenuType == "button" {
			continue
		}

		// 创建菜单对象
		menu := &model.SysMenu{
			Name:         metadata.Title,
			Path:         metadata.Path,
			Component:    metadata.Component,
			Permission:   metadata.Permission,
			Type:         metadata.MenuType,
			Icon:         metadata.Icon,
			OrderNum:     metadata.OrderNum,
			Hidden:       metadata.Hidden,
			KeepAlive:    metadata.KeepAlive,
			AlwaysShow:   metadata.AlwaysShow,
			MenuCategory: metadata.MenuCategory,
		}

		// 添加到映射表和列表中
		menuMap[metadata.Path] = menu
		menuList = append(menuList, menu)
	}

	// 第二步：建立父子关系
	for _, menu := range menuList {
		for _, metadata := range r.RouteMetadataMap {
			if metadata.Path == menu.Path && metadata.ParentPath != "" {
				if parent, ok := menuMap[metadata.ParentPath]; ok {
					menu.ParentID = uint64(parent.ID)
				}
			}
		}
	}

	// 第三步：添加按钮权限
	for _, metadata := range r.RouteMetadataMap {
		if metadata.MenuType == "button" && metadata.ParentPath != "" {
			if parent, ok := menuMap[metadata.ParentPath]; ok {
				button := &model.SysMenu{
					ParentID:     uint64(parent.ID),
					Name:         metadata.Title,
					Path:         metadata.Path,
					Component:    "",
					Permission:   metadata.Permission,
					Type:         "button",
					Icon:         metadata.Icon,
					OrderNum:     metadata.OrderNum,
					MenuCategory: metadata.MenuCategory,
				}
				menuList = append(menuList, button)
			}
		}
	}

	return menuList
}

// GetHandlerFuncName 获取处理函数名称
func GetHandlerFuncName(handler gin.HandlerFunc) string {
	handlerName := runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name()
	segments := strings.Split(handlerName, ".")
	return segments[len(segments)-1]
}

// InitHTTP 初始化HTTP路由
func (r *Router) InitHTTP() {
	// 添加根路径处理程序
	r.Engine.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "Welcome to NiuMaEasyGo API",
			"status":  "running",
		})
	})
}

// InitStatic 初始化静态资源
func (r *Router) InitStatic(path string, relativePath string) {
	r.Engine.Static(relativePath, path)
}

// InitNotFound 初始化404处理
func (r *Router) InitNotFound() {
	r.Engine.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{
			"code":    404,
			"message": "API not found",
		})
	})
}
